home *** CD-ROM | disk | FTP | other *** search
/ Die Speccy' 97 / Die Speccy' 97.iso / amiga_system / the_aminet / comm / bbs / bbbbs85.lha / rexx / bbsMsg.rexx < prev    next >
OS/2 REXX Batch file  |  1995-03-12  |  36KB  |  1,473 lines

  1. /* $VER: bbsMsg.rexx 8.5 (12.3.95)
  2. copyright ⌐ 1990-1995 Richard Lee Stockton
  3. BBBBS offline message conference handler
  4. FREELY DISTRIBUTABLE
  5. */
  6.  
  7. IF ~SHOW('P','QuickSortPort') THEN CALL setup.rexx()
  8. IF ~SHOW('P','QuickSortPort') THEN EXIT 666
  9.  
  10. CALL TIME('R')
  11. OPTIONS RESULTS
  12. SIGNAL ON BREAK_C
  13. SIGNAL ON BREAK_E
  14. SIGNAL ON FAILURE
  15. SIGNAL ON SYNTAX
  16.  
  17. PARSE ARG maxtime name pw 
  18. If ~DATATYPE(maxtime,'N') THEN maxtime=6000
  19.  
  20. title.=''
  21. title.1='BBBBS Message Handler'
  22. title.2='Version 8.4'
  23. title.3='27-Jan-95'
  24.  
  25. IF ADDRESS()='BAUD' THEN
  26.   DO
  27.     CR='0D'x
  28.     frombb=1
  29.   END
  30. ELSE
  31.   DO
  32.     CR=''
  33.     frombb=0
  34.   END
  35.  
  36. CALL config()
  37. clear_marked=0
  38. namemask=COMPRESS(XRANGE(),XRANGE('A','Z')' _-')
  39. IF name='' THEN
  40.   DO
  41.     OPTIONS PROMPT ' Are you 'sysop'? (Yn) > '
  42.     PULL answer
  43.     IF answer='N' THEN
  44.       DO
  45.         SAY
  46.         OPTIONS PROMPT ' Please enter your name > '
  47.         PULL name
  48.         name=cleanstring('1:'name)
  49.         IF name='' THEN EXIT 
  50.       END
  51.     ELSE name=sysop
  52.   END
  53. IF ~EXISTS(bbspath'Users/'name) THEN
  54.   DO
  55.     SAY name 'does not exist!'
  56.     EXIT
  57.   END
  58. CALL loaddata()
  59. IF pw~=password THEN
  60.   DO
  61.     passprompt=pen3' Please Enter Password: '
  62.     DO tries=1 TO 3
  63.       OPTIONS PROMPT passprompt
  64.       PULL newpassword
  65.       SAY def
  66.       IF(password=newpassword) THEN LEAVE tries; /* correct password */
  67.       IF tries=3 THEN
  68.         DO
  69.           SAY 
  70.           SAY 'Access terminated.'
  71.           SAY '*** Bad password ***' newpassword '***'
  72.           EXIT
  73.         END
  74.       passprompt='Incorrect.  Password: ' /* ask again */
  75.     END
  76.     SAY
  77.     SAY' OK, 'name' here we go....'
  78.     SAY
  79.   END
  80. msg.=''
  81. IF readopen(bbspath'Lists/Conferences') THEN
  82.   DO
  83.     DO i=1
  84.       line=READLN(f)
  85.       IF line='END' THEN BREAK
  86.       IF EOF(f) THEN BREAK
  87.       num=WORD(line,1)
  88.       IF DATATYPE(num,'W') THEN msg.num=WORD(line,2)
  89.     END
  90.     CALL CLOSE(f)
  91.   END
  92. SAY '                        'lineup||CR
  93. CALL sortconferences()
  94. searcharg=GETCLIP('BBSMSG_SEARCH')
  95. IF searcharg~='' THEN
  96.   DO
  97.     CALL SETCLIP('BBSMSG_SEARCH')
  98.     CALL search()
  99.     EXIT
  100.   END
  101. IF ARG()=0 THEN
  102.   DO
  103.     DO i=1 TO 3
  104.       SAY CENTER(title.i,75)
  105.     END
  106.     SAY CR
  107.   END
  108. CALL readmessages()
  109. EXIT
  110.  
  111.  
  112. /* sub-routines */
  113.  
  114. config:
  115. arg='s:CONFIG.BBS'
  116. IF ~EXISTS(arg) THEN arg='BBS:BBS_TEXT/CONFIG.BBS'
  117. IF readlines(arg 1) THEN
  118.   DO
  119.     SAY 's:CONFIG.BBS and BBS:BBS_TEXT/CONFIG.BBS are both missing!'CR
  120.     EXIT
  121.   END
  122. compos=POS('/*',lynes.1)
  123. IF compos>0 THEN lynes.1=LEFT(lynes.1,compos-1)
  124. bbsname=STRIP(lynes.1)
  125. sysop=WORD(lynes.2,1)
  126. compos=POS('/*',lynes.3)
  127. IF compos>0 THEN lynes.3=LEFT(lynes.3,compos-1)
  128. exclusion=STRIP(lynes.3)
  129. bbsdevice=WORD(lynes.4,1)
  130. sysoplevel=WORD(lynes.5,1)
  131. bbspath=WORD(lynes.6,1)
  132. IF ~EXISTS(bbspath) THEN
  133.   DO
  134.     SAY bbspath 'does not exist!'CR
  135.     EXIT
  136.   END
  137. testchar=RIGHT(bbspath,1)
  138. IF testchar~='/' & testchar~=':' THEN bbspath=bbspath'/'
  139. msgpath=WORD(lynes.7,1)
  140. IF ~EXISTS(msgpath) THEN
  141.   DO
  142.     SAY msgpath 'does not exist!'CR
  143.     EXIT
  144.   END
  145. testchar=RIGHT(msgpath,1)
  146. IF testchar~='/' & testchar~=':' THEN msgpath=msgpath'/'
  147. msgpath=msgpath'MSG'
  148. DO i=16 TO 41
  149.   j=i-15
  150.   bbsprefs.j=STRIP(WORD(lynes.i,1))
  151. END
  152. IF bbsprefs.10 THEN scratch=bbspath'Scratch'
  153. ELSE scratch='RAM:Scratch'
  154. CALL MAKEDIR(scratch)
  155. IF ~DATATYPE(bbsprefs.16,'W') THEN bbsprefs.16=3
  156. RETURN
  157.  
  158.  
  159. sortconferences:
  160. count=0
  161. smsg.=''
  162. DO i=1 TO level
  163.   IF msg.i='' THEN ITERATE i
  164.   count=count+1
  165.   smsg.count=msg.i i
  166. END
  167. smsg.0=count
  168. IF count>0 THEN CALL QSort(1,count,smsg)
  169. count=0
  170. msgs.=''
  171. DO i=1 TO smsg.0
  172.   tempnum=WORD(smsg.i,2)
  173.   tempdir=WORD(smsg.i,1)
  174.   IF FIND(data.21,tempnum)=0 THEN
  175.     DO
  176.       string=' '
  177.       IF tempnum<10 THEN string=string' '
  178.       string=string || tempnum'.'
  179.       IF WORD(data.22,tempnum)='' | WORD(data.22,tempnum)>=0 THEN
  180.         string=string LEFT(tempdir,20)
  181.       ELSE string=string pen3'-OFF-'def LEFT(tempdir,14)
  182.       count=count+1
  183.       msgs.count=string
  184.     END
  185. END
  186. msgs.0=count%3
  187. IF (count//3)>0 THEN msgs.0=msgs.0+1
  188. DO i=1 TO msgs.0
  189.   DO j=1 TO 2
  190.     k=i+j*msgs.0
  191.     IF k<=count THEN msgs.i=msgs.i msgs.k
  192.   END
  193. END
  194. RETURN
  195.  
  196.  
  197. areaselect:
  198. SAY pen3||LEFT('-',75,'-')||def||CR
  199. DO i=1 TO msgs.0
  200.   SAY msgs.i||CR
  201.   IF i//linesperpage=0 & i<msgs.0 THEN CALL waiting()
  202. END
  203. SAY pen3||LEFT('-',75,'-')||def||CR
  204. temp=getinput(1 0 pen3'Select Message Conference: 'def)
  205. IF ~DATATYPE(temp,'W') | temp<1 | temp>level | FIND(data.21,temp)>0 THEN RETURN 1
  206. IF msg.temp='' THEN RETURN 1
  207. msgdir=temp
  208. RETURN 0
  209.  
  210.  
  211. showmarked:
  212. IF WORDS(data.24)<1 THEN
  213.   DO
  214.     SAY 'You have no marked messages at this time.'CR
  215.     RETURN
  216.   END
  217. fline='These unread conference messages have been ['pen3'M'pen6']arked as addressed to you:'
  218. SAY CR
  219. SAY pen6||fline||def||CR
  220. tempkk=data.24
  221. DO i=1 TO WORDS(tempkk)
  222.   tempk=WORD(tempkk,i)
  223.   PARSE VAR tempk kdir'/'kmsg
  224.   line=RIGHT(kmsg,6) 'in the'pen3 msg.kdir def'conference'
  225.   IF EXISTS(msgpath||tempk) THEN SAY line'.'CR
  226.   ELSE
  227.     DO
  228.       SAY line 'is missing.'CR
  229.       mkw=FIND(data.24,tempk)
  230.       data.24=STRIP(DELWORD(data.24,mkw,1))
  231.       CALL savedata(0)
  232.     END
  233. END
  234. SAY CR
  235. RETURN
  236.  
  237.  
  238. readmessages:
  239. x=GETCLIP('BBSMSG_ARG')
  240. IF x~='' THEN
  241.   DO
  242.     CALL SETCLIP('BBSMSG_ARG')
  243.     colorflag=WORD(x,1)
  244.     IF WORDS(x)>1 THEN arg=SUBSTR(x,WORDINDEX(x,2))
  245.     ELSE arg=''
  246.   END
  247. searcharg=''
  248. DO mainloop=1
  249.   SAY CR
  250.   PARSE VAR arg temp' 'arg .
  251.   IF DATATYPE(temp,'W') THEN msgdir=temp
  252.   ELSE IF LEFT(UPPER(temp),1)='A' THEN
  253.     DO
  254.       CALL newmsgs()
  255.       arg=''
  256.       RETURN
  257.     END
  258.   ELSE IF LEFT(UPPER(temp),1)='M' THEN
  259.     DO
  260.       CALL readmarked()
  261.       arg=''
  262.       RETURN
  263.     END
  264.   ELSE
  265.     DO
  266.       CALL showmarked()
  267.       SAY 'Select Message Conference By' pen3'Number'def', ['pen3'M'def']arked only or ['pen3'A'def']ll Active'CR
  268.       IF areaselect() THEN
  269.         DO
  270.           IF LEFT(temp,1)='A' THEN CALL newmsgs()
  271.           IF LEFT(temp,1)='M' THEN CALL readmarked()
  272.           RETURN
  273.         END
  274.     END
  275.   pline='['pen3'A'def']rchive ['pen3'S'def']earch ['pen3'T'def']oggle ON/OFF'
  276.   pline=pline '['pen3'P'def']ost ['pen3'R'def']ead ['pen3'Q'def']uit (apqRst) > '
  277.   IF WORD(data.22,msgdir)<0 THEN
  278.     pline='['pen3'T'def']oggle ON/OFF ['pen3'Q'def']uit (qT) > '
  279.   IF arg~='' THEN junk=UPPER(LEFT(arg,1))
  280.   ELSE junk=getinput(1 1 pline)
  281.   IF WORD(data.22,msgdir)<0 & junk~='Q' THEN junk='T'
  282.   IF junk='Q' THEN RETURN
  283.   IF junk='P' THEN
  284.     DO
  285.       CALL bbsWrite.rexx(name maxtime-TRUNC(TIME('E')) 'MSG' . . 0 msgdir)
  286.       ITERATE mainloop
  287.     END
  288.   IF junk='A' THEN
  289.     DO
  290.       SAY CR
  291.       CALL msgcount(msgdir)
  292.       junk=getinput(1 0 pen3'RETURN'def' to archive new msgs, ['pen3'Q'def']uit, or enter starting message number > ')
  293.       IF junk='Q' THEN RETURN
  294.       IF DATATYPE(junk,'W') THEN
  295.         DO
  296.           IF junk>lastmess | junk<1 THEN junk=1
  297.           lastread.msgdir=junk-1
  298.           CALL savedata(1)
  299.         END
  300.       CALL SETCLIP('BBS_MSGS','ON')
  301.       SAY 'Archiving messages in the'pen3 msg.msgdir def'Conference...'CR
  302.       lastread.msgdir=countcheck('LastMessage'msgdir 0)
  303.       CALL send2log('Arc: ArcMsgs.rexx' msg.msgdir)
  304.       ADDRESS AREXX ArcMsgs.rexx name msgdir
  305.       DO WHILE GETCLIP('BBS_MSGS')~=''
  306.         CALL DELAY(14)
  307.       END
  308.       SAY 'When completed, the archive will be attached to email addressed to you.'CR
  309.       CALL savedata(1)
  310.       SAY CR
  311.       RETURN
  312.     END
  313.   IF junk='S' THEN
  314.     DO
  315.       searcharg=''
  316.       searcharg=getinput(0 0 pen3'Search Phrase: 'def)
  317.       IF LENGTH(STRIP(searcharg))=0 THEN RETURN
  318.       searcharg=COMPRESS(searcharg,'*')
  319.       SAY CR
  320.       CALL searchmsgdir()
  321.       SAY CR
  322.       SAY lineup'All messages in the'pen3 msg.msgdir def'Conference have been searched.'CR
  323.       SAY CR
  324.       CALL waiting()
  325.       searcharg=''
  326.       ITERATE mainloop
  327.     END
  328.   IF junk='T' THEN
  329.     DO
  330.       line='Turning the' msg.msgdir 'conference'
  331.       IF WORD(data.22,msgdir)<0 THEN
  332.         DO
  333.           line=line pen3'ON'def'.'
  334.           newdata='0'
  335.         END
  336.       ELSE
  337.         DO
  338.           line=line pen3'OFF'def'.'
  339.           newdata='-1'
  340.         END
  341.       SAY line||CR
  342.       dataloc=WORDINDEX(data.22,msgdir)-1
  343.       data.22=DELWORD(data.22,msgdir,1)
  344.       IF dataloc>0 THEN data.22=INSERT(newdata' ',data.22,dataloc)
  345.       CALL sortconferences()
  346.     END
  347.   CALL readmsg(0)
  348.   CALL savedata(1)
  349.   nonstop=0
  350.   arg=''
  351. END
  352. RETURN
  353.  
  354.  
  355. newmsgs:
  356. test=UPPER(LEFT(arg,1))
  357. IF test='' THEN
  358.   test=getinput(1 1 '['pen3'R'def']ead new messages or ['pen3'A'def']rchive for later download. (aR) > ')
  359. IF test='A' THEN
  360.   DO
  361.     CALL SETCLIP('BBS_MSGS','ON')
  362.     SAY CR
  363.     SAY 'Archiving new conference messages...'CR
  364.     CALL send2log('Arc: ArcMsgs.rexx')
  365.     ADDRESS AREXX ArcMsgs.rexx name
  366.     clear_marked=1
  367.     DO i=1 TO level
  368.       IF WORD(data.22,i)~=-1 THEN
  369.         lastread.i=countcheck('LastMessage'i 0)
  370.     END
  371.     DO WHILE GETCLIP('BBS_MSGS')~=''
  372.       CALL DELAY(14)
  373.     END
  374.     SAY 'When completed, the archive will be attached to email addressed to you.'CR
  375.     CALL savedata(1)
  376.     SAY CR
  377.     RETURN
  378.   END
  379. curmsgdir=msgdir
  380. SAY 'Scanning all Conferences for new messages..'CR
  381. DO newi=1 TO level
  382.   IF msg.newi='' THEN ITERATE newi
  383.   msgdir=newi
  384.   CALL readmsg(1)
  385.   IF msgcom='Q' THEN LEAVE newi
  386. END
  387. CALL savedata(1)
  388. msgdir=curmsgdir
  389. nonstop=0
  390. RETURN
  391.  
  392.  
  393. search:
  394. IF searcharg='' THEN searcharg=getinput(0 0 pen3'Search Phrase: 'def)
  395. IF LENGTH(STRIP(searcharg))=0 THEN RETURN
  396. searcharg=COMPRESS(searcharg,'*')
  397. IF getinput(1 1 'Search one conference only? (Ny) > ')='Y' THEN
  398.   DO
  399.     IF areaselect() THEN RETURN
  400.     SAY 'Searching' msg.msgdir 'Message Conference for'pen3 searcharg||def'...'
  401.     SAY
  402.     CALL searchmsgdir()
  403.   END
  404. ELSE
  405.   DO
  406.     SAY 'Searching All Public Message Conferences for'pen3 searcharg||def'...'
  407.     SAY
  408.     DO i=1 TO level
  409.       msgdir=i
  410.       IF msg.msgdir='' | FIND(data.21,msgdir)>0 THEN ITERATE i
  411.       CALL searchmsgdir()
  412.       i=msgdir
  413.       IF msgcom='Q' THEN i=999999
  414.     END
  415.   END
  416. searcharg=''
  417. nonstop=0
  418. SAY CR
  419. IF i<999999 THEN SAY lineup'All available items have been searched.                        'CR
  420. SAY CR
  421. CALL waiting()
  422. RETURN
  423.  
  424.  
  425. searchmsgdir:
  426. msglist=SHOWDIR(msgpath||msgdir)
  427. IF WORDS(msglist)>0 THEN SAY lineup||RIGHT(msg.msgdir,40)||CR
  428. CALL postuser('SEARCH:' msg.msgdir 'for' searcharg)
  429. qi=WORDS(msglist)
  430. msglist=sortnumbers(msglist)
  431. DO wi=1 TO qi
  432.   CALL busywait(8 wi qi)
  433.   messnum=WORD(msglist,wi)%1
  434.   IF textsearch(msgpath||msgdir'/'messnum searcharg) THEN
  435.     DO
  436.       CALL busywait(4 0)
  437.       savelast=lastread.msgdir
  438.       CALL readmsg(0 messnum)
  439.       lastread.msgdir=savelast
  440.       IF msgcom='Q' THEN RETURN
  441.       CALL busywait(4 1)
  442.     END
  443. END
  444. CALL busywait(4 0)
  445. RETURN
  446.  
  447.  
  448. textsearch:
  449. ARG sfile' 'sarg
  450. IF sarg='' THEN RETURN 0
  451. x=OPEN(f,sfile,'R')
  452. IF x=0 THEN RETURN 0
  453. stemp=UPPER(READCH(f,65000))
  454. CALL CLOSE(f)
  455. retflag=0
  456. IF POS(sarg,stemp)>0 THEN retflag=1
  457. RETURN retflag
  458.  
  459.  
  460. sortnumbers:
  461. PARSE ARG slist
  462. IF STRIP(slist)='' THEN RETURN ''
  463. sorted.=''
  464. oldest=999999
  465. newest=0
  466. newlist=''
  467. DO si=1 TO WORDS(slist)
  468.   testword=WORD(slist,si)
  469.   IF ~DATATYPE(testword,'W') THEN
  470.     DO
  471.       testpos=LASTPOS('.',testword)
  472.       IF testpos>0 THEN tempnum=SUBSTR(testword,testpos+1)
  473.       ELSE
  474.         DO
  475.           newlist=testword newlist
  476.           ITERATE si
  477.         END
  478.     END
  479.   ELSE tempnum=testword/1
  480.   IF sorted.tempnum='' THEN
  481.     DO
  482.       sorted.tempnum=testword
  483.       sorted.tempnum.0=1
  484.       IF DATATYPE(tempnum,'W') THEN
  485.         DO
  486.           IF tempnum>newest THEN newest=tempnum
  487.           IF tempnum<oldest THEN oldest=tempnum
  488.         END
  489.     END
  490.   ELSE newlist=newlist testword
  491. END
  492. IF oldest~=999999 & newest~=0 THEN
  493.   DO si=oldest TO newest
  494.     IF sorted.si.0=1 THEN newlist=newlist sorted.si
  495.   END
  496. DROP sorted. oldest newest
  497. RETURN STRIP(newlist)
  498.  
  499.  
  500. postuser:
  501. IF ~frombb | bbsprefs.12~=1 | ~SHOW('P','BBSPOST') THEN RETURN
  502. PARSE ARG parg 
  503. ptext=GETCLIP('BBSPOST4')
  504. IF WORDS(ptext)>4 THEN ptext=LEFT(ptext,WORDINDEX(ptext,5)-1)
  505. ptext=STRIP(ptext)
  506. ptext=CENTER(ptext'   'parg,74)
  507. CALL SETCLIP('BBSPOST4',ptext)
  508. ADDRESS BBSPOST 'UPDATE'
  509. RETURN
  510.  
  511.  
  512. readmsg:
  513. ARG quietflag marknum .
  514. msgcom=''
  515. IF msg.msgdir='' | FIND(data.21,msgdir)>0 THEN RETURN; /* sysop excluded */
  516. IF WORD(data.22,msgdir)=-1 THEN RETURN;                /*  user excluded */
  517. entering='Entering'pen3 msg.msgdir def'Message Conference..'
  518. IF quietflag=0 & marknum='' THEN SAY entering||CR
  519. IF DATATYPE(WORD(data.22,msgdir),'W') THEN
  520.   lastread.msgdir=WORD(data.22,msgdir)
  521. ELSE lastread.msgdir=0
  522. lstwrt=countcheck('LastMessage'msgdir 0)
  523. frstwrt=countcheck('FirstMessage'msgdir 0)
  524. temp=''
  525. IF marknum='' THEN
  526.   DO
  527.     IF lastread.msgdir>=lstwrt | lastread.msgdir<frstwrt THEN
  528.       DO
  529.         CALL msgcount(msgdir)
  530.         IF quietflag=1 & lastread.msgdir=lstwrt THEN RETURN
  531.         IF nonstop=1 THEN temp=lastread.msgdir
  532.         ELSE temp=getinput(1 0 pen3'Enter starting message number > 'def)
  533.         IF temp='' & lastread.msgdir<lstwrt THEN temp=lastread.msgdir
  534.         IF ~DATATYPE(temp,'W') THEN RETURN
  535.         IF temp<frstwrt THEN temp=frstwrt
  536.         IF temp>lstwrt THEN temp=lstwrt
  537.         IF temp<1 THEN temp=1
  538.         lastread.msgdir=temp-1
  539.       END
  540.   END
  541. ELSE lastread.msgdir=marknum-1
  542. CALL postuser('Reading:' msg.msgdir)
  543. IF quietflag=1 THEN SAY entering||CR
  544. t=msgpath||msgdir'.txt'
  545. IF ~terseflag & marknum='' & EXISTS(t) THEN
  546.   DO
  547.     SAY CR
  548.     CALL readlines(t 1)
  549.     saveflag=nonstop
  550.     CALL seelines(1)
  551.     nonstop=saveflag
  552.     SAY CR
  553.   END
  554. dirname=msgpath||msgdir
  555. msglist.=0 /* set read to 0, unread to 1, and reply >=2 */
  556. firstmess=999999
  557. testlist=SHOWDIR(dirname)
  558. DO i=1 TO WORDS(testlist)
  559.   test=WORD(testlist,i)
  560.   IF test>lastread.msgdir THEN msglist.test=1
  561.   IF test<firstmess THEN firstmess=test
  562. END
  563. IF firstmess=999999 THEN firstmess=0
  564. CALL countcheck('FirstMessage'msgdir firstmess)
  565. msgstatus=1
  566. IF temp='' & marknum='' THEN CALL msgcount(msgdir)
  567. late.=''
  568. late.0=0
  569. skipsubj.=''
  570. skipsubj.0=0
  571. DO msgloop=1
  572.   lastreadnum=lastread.msgdir
  573.   DO WHILE msglist.lastreadnum=0 & lastreadnum<lstwrt
  574.     lastreadnum=lastreadnum+1
  575.   END
  576.   lastread.msgdir=lastreadnum
  577.   IF lastreadnum=lstwrt & msglist.lstwrt=0 THEN LEAVE msgloop
  578.   DO mess=lastread.msgdir TO lstwrt+1
  579.     IF marknum~='' THEN
  580.       DO
  581.         IF mess>marknum THEN LEAVE msgloop
  582.         mess=marknum
  583.       END
  584.     IF msglist.mess~=msgstatus THEN ITERATE mess
  585.     IF msgstatus>1 THEN SAY 'Following the thread, level' msgstatus-1'.'CR
  586.     msglist.mess=0
  587.     arg=dirname'/'mess
  588.     IF ~EXISTS(arg) THEN
  589.       DO
  590.         SAY 'Message number' mess 'is missing.'CR
  591.         ITERATE mess
  592.       END
  593.     IF ~readopen(arg) THEN ITERATE mess
  594.     firstline=READLN(f)
  595.     secondline=READLN(f)
  596.     thirdline=READLN(f)
  597.     forthline=READLN(f)
  598.     CALL CLOSE(f)
  599.     CALL killmark(msgdir mess)
  600.     DO skp=1 TO skipsubj.0
  601.       IF forthline=skipsubj.skp THEN ITERATE mess
  602.     END
  603.     IF WORDS(firstline)>2 THEN /* if replies, change their num to >1 */
  604.       DO
  605.         thread=SUBSTR(firstline,WORDINDEX(firstline,4))
  606.         DO tindx=1 TO WORDS(thread)
  607.           test=WORD(thread,tindx)
  608.           IF msglist.test~=0 THEN msglist.test=msgstatus+1
  609.         END
  610.       END
  611.     ELSE thread=''
  612.     savearg=arg
  613.     msgcom='A'
  614.     DO msgloop2=1 WHILE msgcom='A' | msgcom='O'
  615.       CALL readlines(arg 1)
  616.       IF nonstop=1 THEN rnonstop=1
  617.       ELSE rnonstop=0
  618.       CALL seelines(2)
  619.       IF name=WORD(lynes.3,2) THEN
  620.         DO
  621.           IF WORDS(lynes.3)//2=0 THEN
  622.             DO
  623.               lynes.3=lynes.3'  (Rcvd)'
  624.               CALL savelines(arg)
  625.             END
  626.         END
  627.       msgcom=''
  628.       CALL checktime()
  629.       IF rnonstop THEN
  630.         DO
  631.           SAY CR
  632.           nonstop=1
  633.           msgcom=''
  634.         END
  635.       ELSE
  636.         DO
  637.           pline=''
  638.           IF level<=sysoplevel | WORDS(lynes.3)<4 THEN pline='['pen3'A'def']gain'
  639.           IF level>sysoplevel | name=WORD(lynes.2,2) THEN
  640.             pline=pline '['pen3'E'def']dit ['pen3'K'def']ill'
  641.           IF level>sysoplevel THEN pline=pline '['pen3'M'def']ove'
  642.           IF WORDS(lynes.3)>3 THEN pline=pline '['pen3'O'def']riginal'
  643.           pline=pline '['pen3'N'def']onStop ['pen3'R'def']eply'
  644.           IF level=99 THEN pline=pline '['pen3'!'def']'
  645.           pline=pline '['pen3'S'def']kip ['pen3'Q'def']uit ['pen3'?'def']'
  646.           msgcom=getinput(1 0 STRIP(pline)' > ')
  647.           CALL cleanline(0)
  648.         END
  649.       IF DATATYPE(msgcom,'W') & EXISTS(dirname'/'msgcom) THEN
  650.         DO
  651.           arg=dirname'/'msgcom
  652.           IF msgcom>lastread.msgdir THEN lastread.msgdir=msgcom
  653.           msgcom='A'
  654.           ITERATE msgloop2
  655.         END
  656.       ELSE msgcom=LEFT(msgcom,1)
  657.       IF msgcom='Q' THEN LEAVE msgloop
  658.       ELSE IF msgcom='!' & level>sysoplevel THEN
  659.         DO
  660.           CALL DELETE(arg)
  661.           newchar=LEFT(lynes.1,1)
  662.           IF newchar~='!' THEN newchar='!!'
  663.           ELSE newchar='  '
  664.           lynes.1=OVERLAY(newchar,lynes.1,1,2)
  665.           CALL savelines(arg)
  666.           ITERATE msgloop2
  667.         END
  668.       ELSE IF msgcom='A' THEN ITERATE msgloop2
  669.       ELSE IF msgcom='M' & level>sysoplevel THEN
  670.         DO
  671.           prevmsgdir=msgdir
  672.           If ~areaselect() THEN
  673.             DO
  674.               CALL MAKEDIR(msgpath||msgdir)
  675.               himsg=countcheck('LastMessage'msgdir 0)+1
  676.               lynes.1='  Msg:' himsg
  677.               lynes.3='   To:' WORD(lynes.3,2)
  678.               lynes.5=STRIP(DELWORD(lynes.5,8,1)) msg.msgdir
  679.               nlyn=lynes.0+1
  680.               lynes.0=nlyn
  681.               lynes.nlyn=' *** Moved from the' msg.prevmsgdir 'conference ***'
  682.               CALL savelines(msgpath||msgdir'/'himsg)
  683.               CALL countcheck('LastMessage'msgdir himsg)
  684.               CALL msgmark(WORD(lynes.3,2) msgdir himsg)
  685.               CALL readlines(arg 1)
  686.               CALL DELETE(arg)
  687.               CALL DELAY(28)
  688.               lynes.0=7
  689.               lynes.7='*** Moved to the' msg.msgdir 'conference, message #'himsg' ***'
  690.               CALL savelines(arg)
  691.             END
  692.           msgdir=prevmsgdir
  693.           msgcom='A'
  694.         END
  695.       ELSE IF msgcom='N' THEN
  696.         DO
  697.           nonstop=1
  698.           msgcom=''
  699.         END
  700.       ELSE IF msgcom='H' | msgcom='?' THEN
  701.         DO
  702.           SAY pen3' - HELP with the Read Messages commands -'def||CR
  703.           SAY ' RETURN reads the next message in line.'CR
  704.           SAY ' 34 will read message number 34, if it exists in this conference.'CR
  705.           SAY ' A  reads this message Again (in case it scrolled off screen).'CR
  706.           IF level>sysoplevel | name=WORD(lynes.2,2) THEN
  707.             DO
  708.           SAY ' E  puts this message into the online Editor.'CR
  709.           SAY ' K  deletes a message you wrote. you cannot Kill others!'CR
  710.             END
  711.           IF level>sysoplevel THEN
  712.           SAY ' M  move this message to a new conference.'CR
  713.           SAY ' N  displays all new messages without pausing. CTRL-E to Exit!'CR
  714.           SAY ' O  if this message is a reply, will read the Original message.'CR
  715.           SAY ' R  enters the message editor to Reply to this message.'CR
  716.           SAY ' S  allows you to Skip threads or conferences.'CR
  717.         IF level=99 THEN
  718.           SAY ' !  toggles the do-not-purge! flag for this message.'CR
  719.           SAY ' Q  returns to the message menu. (Quit)'CR
  720.           SAY CR
  721.           CALL waiting()
  722.           msgcom='A'
  723.           IF waitchar='Q' THEN LEAVE msgloop
  724.         END
  725.       ELSE IF msgcom='E' THEN
  726.         DO
  727.           IF level>sysoplevel | name=WORD(lynes.2,2) THEN
  728.             DO
  729.               sline=7
  730.               IF level>sysoplevel THEN sline=1
  731.               CALL bbsEd.rexx(sline arg name maxtime)
  732.               msgcom='A'
  733.             END
  734.         END
  735.       ELSE IF msgcom='S' & mess<lstwrt THEN
  736.         DO
  737.           stemp=''
  738.           req='Skip'
  739.           IF WORDS(lynes.1)>2 THEN req=req 'this ['pen3'T'def']hread or'
  740.           ELSE SAY 'There are no replies to this message.'CR
  741.           req=req 'the entire ['pen3'C'def']onference? ('
  742.           IF WORDS(lynes.1)>2 THEN tst='cqt'
  743.           ELSE tst='cq'
  744.           DO WHILE POS(stemp,UPPER(tst))=0
  745.             stemp=getinput(1 1 req||tst') >')
  746.           END
  747.           IF stemp='T' THEN
  748.             DO
  749.               SAY CR
  750.               SAY pen3 forthline||def||CR
  751.               SAY 'Skipping messages associated with this message...'CR
  752.               SAY CR
  753.               DO i=lastread.msgdir TO lstwrt
  754.                 IF msglist.i>1 THEN msglist.i=0
  755.               END
  756.               skipsubj.0=skipsubj.0+1
  757.               sksb=skipsubj.0
  758.               skipsubj.sksb=forthline
  759.             END
  760.           ELSE IF stemp='C' THEN
  761.             DO
  762.               SAY pen3'Skipping to the last message in the'def msg.msgdir pen3'conference.'def||CR
  763.               lastread.msgdir=lstwrt-1
  764.               lw=lstwrt-1
  765.               msglist.lw=0
  766.               msglist.lstwrt=1
  767.               LEAVE mess
  768.             END
  769.         END
  770.       ELSE IF msgcom='K' THEN
  771.         DO
  772.           IF level>sysoplevel | name=WORD(lynes.2,2) THEN
  773.             DO
  774.               IF getinput(1 1 'Really delete' arg'? (Ny) > ')='Y' THEN
  775.                 DO
  776.                   IF DELETE(arg)=1 THEN
  777.                     SAY pen3||arg||def' has been deleted.'CR
  778.                   msg.msgdir.0=msg.msgdir.0-1
  779.                 END
  780.             END
  781.         END
  782.       ELSE IF msgcom='O' THEN   /* go back and read original */
  783.         DO
  784.           IF WORDS(lynes.3)>3 THEN
  785.             DO
  786.               temp=WORD(lynes.3,4)
  787.               arg=dirname'/'temp
  788.             END
  789.           ELSE SAY 'This is the original message.'CR
  790.         END
  791.       ELSE IF msgcom='R' THEN
  792.         DO
  793.           IF thread~='' & marknum='' THEN
  794.             DO
  795.               li='Read the replies to this message before answering? (nY) > '
  796.               IF getinput(1 1 li)~='N' THEN
  797.                 DO
  798.                   n=late.0+1
  799.                   late.0=n
  800.                   late.n=msgstatus
  801.                   late.n.0=arg
  802.                   ITERATE msgloop2
  803.                 END
  804.             END
  805.           CALL do_reply(mess)
  806.         END
  807.       ELSE IF arg~=savearg THEN /* Continue */
  808.         DO
  809.           msgcom='A'
  810.           arg=savearg
  811.         END
  812.     END
  813.     IF thread~='' THEN
  814.       DO
  815.         thread=''
  816.         msgstatus=msgstatus+1
  817.       END
  818.   END
  819.   IF msgstatus>0 THEN
  820.     DO
  821.       IF msgstatus>1 THEN msgstatus=msgstatus-1
  822.       CALL do_late()
  823.       CALL postuser('Reading:' msg.msgdir)
  824.     END
  825. END
  826. msgstatus=0
  827. CALL do_late()
  828. DROP msglist. skipsubj. late.
  829. IF quietflag~=1 THEN nonstop=0
  830. RETURN
  831.  
  832.  
  833. do_late:
  834. DO lt=1 TO late.0
  835.   IF late.lt='' THEN ITERATE lt
  836.   IF msgstatus<=late.lt THEN
  837.     DO
  838.       SAY CR
  839.       SAY bak2' Reviewing message marked for reply...'def||CR
  840.       late.lt=''
  841.       CALL readlines(late.lt.0 1)
  842.       CALL seelines(2)
  843.       ps='Reply to this message? (nY) > '
  844.       IF getinput(1 1 ps)~='N' THEN CALL do_reply(0)
  845.     END
  846. END
  847. RETURN
  848.  
  849.  
  850. docity:
  851. PARSE ARG citi
  852. citi=TRANSLATE(citi,'          ','+-.,*/()<>')
  853. DO i=WORDS(citi) TO 1 BY -1
  854.   IF DATATYPE(WORD(citi,i),'N') THEN citi=STRIP(DELWORD(citi,i,1))
  855.   IF UPPER(WORD(citi,i))='USA' THEN citi=STRIP(DELWORD(citi,i,1))
  856. END
  857. citi=SPACE(citi,1)
  858. RETURN STRIP(citi)
  859.  
  860.  
  861. do_reply:
  862. ARG mes
  863. CALL postuser('Writing:' msg.msgdir)
  864. msgnum=WORD(lynes.1,2)
  865. toname=WORD(lynes.2,2)
  866. orig=dirname'/'msgnum
  867. subj=STRIP(SUBSTR(lynes.4,7))
  868. IF getinput(1 1 'Should this reply be private for'pen3 toname def'only? (yN) > ')='Y' THEN
  869.   DO
  870.     comm=name maxtime-TIME('E') 'MAIL' toname orig 0 0 subj
  871.     CALL bbsWrite.rexx(comm)
  872.     RETURN
  873.   END
  874. comm=name maxtime-TIME('E') 'REPLY' toname orig msgnum msgdir subj
  875. IF bbsWrite.rexx(comm) THEN
  876.   DO
  877.     IF EXISTS(orig) THEN
  878.       DO
  879.         IF readlines(orig 1) THEN BREAK
  880.         xmsg=countcheck('LastMessage'msgdir mes)
  881.         IF WORDS(lynes.1)>3 THEN lynes.1=lynes.1 xmsg
  882.         ELSE lynes.1=lynes.1'   Reply' xmsg
  883.         CALL DELAY(28)    /* allow 1/2 sec for read to close */
  884.         CALL savelines(orig)
  885.       END
  886.   END
  887. RETURN
  888.  
  889.  
  890. msgmark:
  891. PARSE ARG markname markdir markmsg .
  892. IF OPEN(f,bbspath'Users/'markname,'R')=0 THEN RETURN
  893. mlines.=''
  894. DO mi=1
  895.   temp=READLN(f)
  896.   IF EOF(f) THEN LEAVE mi
  897.   mlines.mi=STRIP(temp)
  898. END
  899. CALL CLOSE(f)
  900. mlines.0=mi-1
  901. CALL DELAY(28)
  902. mlines.24=STRIP(mlines.24 markdir'/'markmsg)
  903. IF OPEN(f,bbspath'Users/'markname,'W')=0 THEN RETURN
  904. DO mi=1 TO mlines.0
  905.   CALL WRITELN(f,mlines.mi)
  906. END
  907. CALL CLOSE(f)
  908. RETURN
  909.  
  910.  
  911. checktime:
  912. IF ~frombb THEN RETURN
  913. IF TIME('E')>maxtime THEN EXIT
  914. IF TIME('E')>(maxtime-120) THEN SAY '*** Less than 2 minutes left! ***'CR
  915. MSG RIGHT(' ',66-LENGTH(name)) '1B'x'M'||''||''||' 'name' level 'level' '||''
  916. CALL checkdcd()
  917. RETURN
  918.  
  919.  
  920. waiting:
  921. CALL checktime()
  922. IF waitchar='Q' THEN
  923.   DO
  924.     waitchar=''
  925.     RETURN
  926.   END
  927. waitchar=''
  928. IF nonstop=1 THEN RETURN
  929. OPTIONS PROMPT pen3'                          RETURN=Continue 'def
  930. PULL waitchar
  931. CALL cleanline(1)
  932. CALL checkdcd()
  933. RETURN
  934.  
  935.  
  936. waiting2:
  937. CALL checktime()
  938. IF nonstop=1 THEN RETURN 0
  939. waitchar=getinput(1 1 pen3'   Q=Quit   N=Non-Stop   RETURN=Continue  'def)
  940. IF waitchar='N' THEN
  941.   DO
  942.     nonstop=1
  943.     SAY lineup||pen3'To EXIT non-stop scrolling of text, press CTRL-E        'def||CR
  944.     SAY CR
  945.     CALL DELAY(99)
  946.     waitchar=''
  947.   END
  948. CALL cleanline(1)
  949. CALL checkdcd()
  950. IF waitchar='Q' THEN RETURN 1
  951. RETURN 0
  952.  
  953.  
  954. killmark:
  955. PARSE ARG kdir kmsg .
  956. IF data.24='' THEN RETURN
  957. markword=FIND(data.24,kdir'/'kmsg)
  958. IF markword>0 THEN data.24=STRIP(DELWORD(data.24,markword,1))
  959. RETURN
  960.  
  961.  
  962. readmarked:
  963. mrknum=WORDS(data.24)
  964. IF mrknum=0 THEN RETURN
  965. SAY 'Reading only messages addressed to you...'CR
  966. mrklist=data.24
  967. msgcom=''
  968. DO rmki=1 TO mrknum WHILE msgcom~='Q'
  969.   tempk=WORD(mrklist,rmki)
  970.   PARSE VAR tempk mkdir'/'mkmsg .
  971.   IF ~EXISTS(msgpath||tempk) THEN
  972.     DO
  973.       CALL killmark(mkdir mkmsg)
  974.       SAY CR
  975.       SAY 'Message number' mkmsg 'in the' msg.mkdir 'conference is missing!'CR
  976.       SAY CR
  977.       ITERATE rmki
  978.     END
  979.   msgdir=mkdir
  980.   savelast=lastread.msgdir
  981.   CALL readmsg(1 mkmsg)
  982.   IF mkmsg>savelast THEN lastread.msgdir=mkmsg
  983.   ELSE lastread.msgdir=savelast
  984. END
  985. CALL savedata(1)
  986. RETURN
  987.  
  988.  
  989. msgcount:
  990. ARG countdir .
  991. lastmess=0
  992. totmsgs=0
  993. unred=0
  994. IF ~EXISTS(msgpath||countdir) THEN RETURN
  995. IF STATEF(msgpath||countdir)=msg.countdir.1 THEN totmsgs=msg.countdir.0
  996. ELSE
  997.   DO
  998.     totmsgs=WORDS(SHOWDIR(msgpath||countdir))
  999.     msg.countdir.0=totmsgs
  1000.     msg.countdir.1=STATEF(msgpath||countdir)
  1001.   END
  1002. IF countdir>level | FIND(data.21,i)>0 THEN RETURN
  1003. lastread.countdir=WORD(data.22,countdir)
  1004. IF ~DATATYPE(lastread.countdir,'W') THEN lastread.countdir=0
  1005. lastmess=countcheck('LastMessage'countdir 0)
  1006. IF lastread.countdir<0 THEN RETURN
  1007. firstmess=countcheck('FirstMessage'countdir 0)
  1008. IF lastread.countdir<firstmess THEN lastread.countdir=firstmess-1
  1009. IF lastmess>0 THEN
  1010.   IF lastread.countdir>=0 THEN
  1011.     DO
  1012.       IF lastread.countdir<(firstmess-1) THEN lastread.countdir=firstmess-1
  1013.       unred=lastmess-lastread.countdir
  1014.       IF unred>totmsgs THEN unred=totmsgs
  1015.       cline=RIGHT(unred,5) 'new of' RIGHT(lastmess,5) 'messages,'
  1016.       cline=cline RIGHT(totmsgs,5) 'still online in' 
  1017.       cline=cline RIGHT(countdir,2)',' msg.countdir
  1018.       SAY pen6||cline||def||CR
  1019.     END
  1020. RETURN
  1021.  
  1022.  
  1023. searchmsgdir:
  1024. msglist=SHOWDIR(msgpath||msgdir)
  1025. IF WORDS(msglist)>0 THEN SAY lineup||RIGHT(msg.msgdir,40)||CR
  1026. qi=WORDS(msglist)
  1027. DO wi=1 TO qi
  1028.   CALL busywait(8 wi qi)
  1029.   messnum=WORD(msglist,wi)%1
  1030.   IF textsearch(msgpath||msgdir'/'messnum searcharg) THEN
  1031.     DO
  1032.       CALL busywait(4 0)
  1033.       savelast=lastread.msgdir
  1034.       CALL readmsg(0 messnum)
  1035.       lastread.msgdir=savelast
  1036.       IF msgcom='Q' THEN RETURN
  1037.       CALL busywait(4 1)
  1038.     END
  1039. END
  1040. CALL busywait(4 0)
  1041. RETURN
  1042.  
  1043.  
  1044. busywait:
  1045. ARG bii bi bt 
  1046. IF bii>4 & bi//(10*bii)=0 THEN CALL checkdcd()
  1047. IF bbsprefs.21=0 THEN RETURN
  1048. IF bi<1 THEN
  1049.   DO
  1050.     CALL WRITECH(STDOUT,'080808'x)
  1051.     IF ni<1 & i>999998 & wi>999998 THEN SAY CR
  1052.     RETURN
  1053.   END
  1054. IF bi=1 THEN CALL WRITECH(STDOUT,'   ')
  1055. IF bi//(bii%2)~=0 THEN RETURN
  1056. b=bi//bii
  1057. IF b=0 | b=bii%2 THEN
  1058.   DO
  1059.     tp=RIGHT((bi*100)%bt,2)'%'
  1060.     CALL WRITECH(STDOUT,'080808'x||tp)
  1061.   END
  1062. RETURN
  1063.  
  1064.  
  1065. cleanline:
  1066. ARG lflag .
  1067. IF nonstop=0 & clr~='' & frombb THEN
  1068.   DO
  1069.     Send clr
  1070.     RETURN
  1071.   END
  1072. cline=lineup||LEFT(' ',78)
  1073. IF lflag=1 THEN cline=cline||lineup
  1074. SAY cline||CR
  1075. RETURN
  1076.  
  1077.  
  1078. countcheck:
  1079. PARSE ARG fname' 'cknum .
  1080. fname=bbspath'Numbers/'fname
  1081. IF ~EXISTS(fname) THEN
  1082.   DO
  1083.     IF cknum=0 THEN RETURN 0
  1084.     IF OPEN(f,fname,'W')=0 THEN RETURN 0
  1085.     CALL WRITELN(f,cknum)
  1086.     CALL CLOSE(f)
  1087.     RETURN cknum
  1088.   END
  1089. IF OPEN(f,fname,'R')=0 THEN
  1090.   DO
  1091.     CALL DELAY(99)
  1092.     IF OPEN(f,fname,'R')=0 THEN RETURN cknum
  1093.   END
  1094. retval=STRIP(READLN(f))
  1095. CALL CLOSE(f)
  1096. IF ~DATATYPE(retval,'W') THEN retval=0
  1097. IF ~DATATYPE(cknum,'W') THEN cknum=0
  1098. IF retval<cknum THEN
  1099.   DO
  1100.     IF OPEN(f,fname,'W')~=0 THEN
  1101.       DO
  1102.         CALL WRITELN(f,cknum)
  1103.         CALL CLOSE(f)
  1104.         RETURN cknum
  1105.       END
  1106.   END
  1107. RETURN retval
  1108.  
  1109.  
  1110. getinput:
  1111. PARSE ARG upflag' 'oneflag' 'pline
  1112. CALL checktime()
  1113. OPTIONS PROMPT pline
  1114. PARSE PULL inarg
  1115. inarg=STRIP(inarg)
  1116. IF upflag THEN inarg=UPPER(inarg)
  1117. IF oneflag THEN inarg=LEFT(inarg,1)
  1118. inarg=cleanstring(0':'inarg)
  1119. RETURN inarg
  1120.  
  1121.  
  1122. checkdcd:
  1123. IF ~frombb THEN RETURN
  1124. dcd
  1125. IF RC=0 THEN
  1126.   DO
  1127.     DO dcds=1 TO 3  /* 5 second delay */
  1128.       CALL DELAY(50)
  1129.       dcd
  1130.       IF RC~=0 THEN RETURN
  1131.     END
  1132.     dcd
  1133.     IF RC=0 THEN EXIT
  1134.   END
  1135. xmsg=GETCLIP('BBS_MESSAGE')
  1136. IF xmsg~='' THEN
  1137.   DO
  1138.     CALL SETCLIP('BBS_MESSAGE')
  1139.     SAY CR
  1140.     SAY bak2' Message From BBBBS: 'def||CR
  1141.     SAY xmsg||CR
  1142.     SAY CR
  1143.     CALL waiting()
  1144.   END
  1145. IF POS('G',GETCLIP('BBS_COMMAND'))>0 THEN EXIT
  1146. RETURN
  1147.  
  1148.  
  1149. cleanstring:
  1150. PARSE ARG nflag':'cstr
  1151. IF nflag=1 THEN
  1152.   DO
  1153.     cstr=COMPRESS(cstr,"'`")
  1154.     cstr=TRANSLATE(cstr,,namemask)
  1155.     cstr=SPACE(cstr,1,'_')
  1156.     RETURN cstr
  1157.   END
  1158. bot=XRANGE(,'1F'x)
  1159. IF nflag=2 THEN bot=COMPRESS(bot,'1B'x)  /* ESC for ANSI */
  1160. ELSE cstr=strip_ansi(cstr)
  1161. top=XRANGE('7F'x)
  1162. cstr=COMPRESS(cstr,bot||top)
  1163. IF nflag=0 THEN cstr=STRIP(cstr)
  1164. RETURN cstr
  1165.  
  1166.  
  1167. do_eleven:
  1168. ARG am tc at .
  1169. data.11=am 'minutes per call,' tc 'calls per day,'
  1170. data.11=data.11 at 'more calls today'
  1171. RETURN
  1172.  
  1173.  
  1174. savedata:
  1175. ARG messflag .
  1176. IF data.5='' THEN RETURN
  1177. SAY 'Updating...             'lineup||CR
  1178. temp=GETCLIP(name'_UPDATE')
  1179. IF temp~='' THEN
  1180.   DO
  1181.     CALL SETCLIP(name'_UPDATE')
  1182.     PARSE VAR temp upfiles' 'upbytes' 'upmail' 'upmsg
  1183.     IF upfiles>0 THEN
  1184.       DO
  1185.         files=WORD(data.14,1)
  1186.         bytes=WORD(data.14,3)
  1187.         IF DATATYPE(files,'W') THEN upfiles=upfiles+files
  1188.         IF DATATYPE(bytes,'W') THEN bytes=upbytes
  1189.         data.14=upfiles 'files' bytes 'bytes.' DATE()
  1190.       END
  1191.     IF upmail>0 THEN
  1192.       DO
  1193.         mail=WORD(data.17,2)
  1194.         IF DATATYPE(mail,'W') THEN upmail=upmail+mail
  1195.         data.17=WORD(data.17,1) upmail WORD(data.17,3)
  1196.       END
  1197.     IF upmsg~='' THEN
  1198.       DO
  1199.         temp=data.23
  1200.         DO i=1 TO level
  1201.           smsg=WORD(temp,i)
  1202.           IF ~DATATYPE(smsg,'W') THEN smsg=0
  1203.           IF FIND(upmsg,i) THEN smsg=smsg+1
  1204.           data.23=data.23 smsg
  1205.         END
  1206.       END
  1207.   END
  1208. SIGNAL OFF BREAK_E
  1209. IF frombb THEN
  1210.   DO
  1211.     Status Trans
  1212.     data.6=STRIP(RESULT)
  1213.   END
  1214. IF lastbrowse>0 THEN
  1215.   DO
  1216.     IF WORDS(data.16)>1 THEN data.16=DELWORD(data.16,1,1)
  1217.     ELSE data.16=DATE('S') TIME()
  1218.     data.16=lastbrowse data.16
  1219.   END
  1220. IF messflag THEN
  1221.   DO
  1222.     userexclude.=0
  1223.     DO si=1 TO WORDS(data.22)
  1224.       IF WORD(data.22,si)=-1 THEN userexclude.si=1
  1225.     END
  1226.     data.22=''
  1227.     data.23=''
  1228.     DO si=1 TO level
  1229.       IF ~DATATYPE(lastread.si,'W') THEN lastread.si=0
  1230.       IF userexclude.si THEN data.22=data.22 '-1'
  1231.       ELSE data.22=data.22 lastread.si
  1232.       IF ~DATATYPE(totwrit.si,'W') THEN totwrit.si=0
  1233.       data.23=data.23 totwrit.si
  1234.     END
  1235.   END
  1236. IF clear_marked=1 THEN data.24=''
  1237. clear_marked=0
  1238. IF writeopen(bbspath'USERS/'name)=0 THEN RETURN
  1239. IF data.0<27 THEN data.0=27
  1240. DO i=1 TO data.0
  1241.   CALL WRITELN(f,data.i)
  1242. END
  1243. CALL CLOSE(f)
  1244. SAY 'User' name 'has been updated.'CR
  1245. RETURN
  1246.  
  1247.  
  1248. loaddata:
  1249. IF name='' THEN RETURN 0
  1250. IF ~readopen(bbspath'USERS/'name) THEN RETURN 0
  1251. data.=''
  1252. DO i=1
  1253.   line=READLN(f)
  1254.   IF EOF(f) THEN BREAK
  1255.   data.i=line
  1256. END
  1257. data.0=i-1
  1258. CALL CLOSE(f)
  1259. city=docity(data.3)
  1260. winnings=WORD(data.18,1)
  1261. IF ~DATATYPE(winnings,'N') THEN winnings=0
  1262. IF WORDS(data.16)<3 THEN data.16='0 19900101 00:00:00'
  1263. lastbrowse=WORD(data.16,1)
  1264. IF ~DATATYPE(lastbrowse,'W') THEN lastbrowse=0
  1265. level=data.20
  1266. DO i=1 TO level
  1267.   lastread.i=WORD(data.22,i)
  1268.   IF ~DATATYPE(lastread.i,'W') THEN lastread.i=0
  1269.   totwrit.i=WORD(data.23,i)
  1270.   IF ~DATATYPE(totwrit.i,'W') THEN totwrit.i=0
  1271. END
  1272. password=data.5
  1273. IF frombb THEN
  1274.   DO
  1275.     IF data.6='' THEN
  1276.       DO
  1277.         Status Trans
  1278.         data.6=RESULT
  1279.       END
  1280.     ELSE
  1281.       DO
  1282.         IF RIGHT(UPPER(data.6),2)='-G' THEN data.6='G'
  1283.         IF RIGHT(UPPER(data.6),3)='-1K' THEN data.6='K'
  1284.         IF LEFT(UPPER(data.6),1)='A' THEN data.6='Z'
  1285.         IF frombb THEN Set UPPER(LEFT(data.6,1))
  1286.       END
  1287.   END
  1288. IF ~DATATYPE(data.7,'W') THEN data.7=20
  1289. IF data.7<5 THEN data.7=5
  1290. linesperpage=data.7
  1291. IF ~frombb THEN linesperpage=20
  1292. IF FIND(UPPER(data.8),'TERSE')>0 THEN terseflag=1
  1293. ELSE terseflag=0
  1294. IF FIND(UPPER(data.8),'COLOR')>0 THEN colorflag=1
  1295. ELSE colorflag=0
  1296. CALL colors(colorflag)
  1297. clr=''
  1298. IF frombb & FIND(UPPER(data.8),'CLEAR')>0 THEN clr='0C'x
  1299. menu='ALL'
  1300. IF FIND(UPPER(data.8),'MENUS')>0 THEN
  1301.   DO
  1302.     menuflag=1
  1303.     menu='MAIN'
  1304.   END
  1305. ELSE IF FIND(UPPER(data.8),'MENU')>0 THEN menuflag=1
  1306. ELSE menuflag=0
  1307. IF level=0 THEN menu='NEW'
  1308. IF DATATYPE(WORD(data.11,3),'W') THEN
  1309.   DO
  1310.     PARSE VAR data.11 amins . atimes .
  1311.     CALL do_eleven(amins bbsprefs.16 atimes)
  1312.   END
  1313. data.21=UPPER(data.21)
  1314. RETURN 1
  1315.  
  1316.  
  1317. savelines:
  1318. PARSE ARG tempname .
  1319. IF OPEN(f,tempname,'W')=0 THEN
  1320.   DO
  1321.     line='***' tempname 'failed to open for saving!'
  1322.     CALL send2log(line)
  1323.     SAY line||CR
  1324.     RETURN 1
  1325.   END
  1326. DO wi=1 TO lynes.0
  1327.   CALL WRITELN(f,lynes.wi)
  1328. END
  1329. CALL CLOSE(f)
  1330. RETURN 0
  1331.  
  1332.  
  1333. seelines:
  1334. ARG fancy .
  1335. DO i=1 TO lynes.0
  1336.   IF fancy=0 THEN SAY lynes.i||def||CR
  1337.   ELSE
  1338.     DO
  1339.       IF LEFT(lynes.i,2)=': ' & WORDS(lynes.i)=2 THEN ITERATE i
  1340.       ELSE IF LEFT(lynes.i,10)='Directory ' | LEFT(lynes.i,5)='=====' THEN
  1341.         SAY pen3||lynes.i||def||CR
  1342.       ELSE SAY lynes.i||CR
  1343.       IF fancy=2 & colorflag=1 THEN
  1344.         DO
  1345.           IF searcharg~='' THEN
  1346.             DO
  1347.               testpos=POS(UPPER(searcharg),UPPER(lynes.i))
  1348.               IF testpos>0 THEN
  1349.                 SAY LEFT(' ',testpos-1)||pen3||lineup||UPPER(searcharg)||def||CR
  1350.             END
  1351.           IF i=1 THEN
  1352.             IF WORD(lynes.1,3)='Reply' THEN
  1353.               DO
  1354.                 testpos=WORDINDEX(lynes.1,3)
  1355.                 SAY LEFT(' ',testpos-1)||pen3||lineup||SUBSTR(lynes.1,testpos)||def||CR
  1356.               END
  1357.         END
  1358.     END
  1359.   IF i//linesperpage=0 & i<lynes.0 THEN
  1360.     IF waiting2() THEN LEAVE i
  1361. END
  1362. nonstop=0
  1363. RETURN
  1364.  
  1365.  
  1366. writeopen:
  1367. PARSE ARG fname
  1368. CALL CLOSE(f)
  1369. ok=OPEN(f,fname,'W')
  1370. IF ok~=0 THEN RETURN 1
  1371. line=fname 'failed to open for writing!'
  1372. SAY line||CR
  1373. CALL send2log(line)
  1374. RETURN 0
  1375.  
  1376.  
  1377. readopen:
  1378. PARSE ARG fname
  1379. ok=OPEN(f,fname,'R')
  1380. IF ok~=0 THEN RETURN 1
  1381. line=fname 'failed to open for reading!'
  1382. SAY line||CR
  1383. CALL send2log(line)
  1384. RETURN 0
  1385.  
  1386.  
  1387. readlines:
  1388. CALL CLOSE(f)
  1389. PARSE ARG tempname readstart .
  1390. IF ~readopen(tempname) THEN RETURN 1
  1391. IF readstart<2 THEN lynes.=''
  1392. DO ri=readstart
  1393.   line=READLN(f)
  1394.   IF EOF(f) THEN BREAK
  1395.   lynes.ri=line
  1396. END
  1397. lynes.0=ri-1
  1398. CALL CLOSE(f)
  1399. DO ri=lynes.0 TO 0 BY -1 WHILE LENGTH(lynes.ri)=0 | LEFT(UPPER(lynes.ri),2)='/E' | LEFT(UPPER(lynes.ri),2)='/S'
  1400. END
  1401. lynes.0=ri
  1402. RETURN 0
  1403.  
  1404.  
  1405. strip_ansi:
  1406. PARSE ARG aline 
  1407. n=POS('1B'x,aline)
  1408. DO WHILE n>0
  1409.   DO k=2
  1410.     IF DATATYPE(SUBSTR(aline,n+k,1),'M') | (n+k+1)>LENGTH(aline) THEN
  1411.       leave k
  1412.   END
  1413.   aline=DELSTR(aline,n,k+1)
  1414.   n=POS('1B'x,aline)
  1415. END
  1416. RETURN aline
  1417.  
  1418.  
  1419. send2log:
  1420. PARSE ARG sendline
  1421. IF ~frombb THEN RETURN
  1422. logfile=bbspath'Logs/log.'DATE('S')    /* daily logs */
  1423. fl='W'
  1424. IF EXISTS(logfile) THEN fl='A'
  1425. IF ~OPEN('log',logfile,fl) THEN
  1426.   DO
  1427.     IF ~OPEN('log',logfile,fl) THEN
  1428.       DO
  1429.         SAY 'failed to open log file'
  1430.         RETURN
  1431.      END
  1432.   END
  1433. CALL WRITELN('log','bbsMsg:' sendline)
  1434. CALL CLOSE('log')
  1435. RETURN
  1436.  
  1437.  
  1438. colors:
  1439. ARG onoff
  1440. IF onoff THEN
  1441.   DO;def='';pen2='';pen3='';pen6='';bak2='';END
  1442. ELSE
  1443.   DO;def='';pen2='';pen3='';pen6='';bak2='';END
  1444. lineup='1B'x'M'
  1445. RETURN
  1446.  
  1447.  
  1448. BREAK_E:
  1449. i=999999
  1450. ri=999999
  1451. wi=999999
  1452. newi=999999
  1453. RETURN
  1454.  
  1455.  
  1456. BREAK_C:
  1457. EXIT
  1458.  
  1459.  
  1460. FAILURE:
  1461. SYNTAX:
  1462. lin.1=''ERRORTEXT(RC)''
  1463. lin.2=SIGL-1     SOURCELINE(SIGL-1)
  1464. lin.3=SIGL ''SOURCELINE(SIGL)''
  1465. lin.4=SIGL+1     SOURCELINE(SIGL+1)
  1466. DO er=1 TO 4
  1467.   IF level>sysoplevel | ~frombb THEN SAY 'bbsMsg:' lin.er||CR
  1468.   IF frombb THEN CALL send2log(lin.er)
  1469. END
  1470. EXIT
  1471.  
  1472. /* bbsMsg.rexx */
  1473.